package cn.blossoming.controller;

import cn.blossoming.service.base.config.SpringConfiguration;
import cn.blossoming.service.base.consts.SessionConst;
import cn.blossoming.service.base.utils.JacksonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.HeaderHttpSessionStrategy;
import org.springframework.session.web.http.HttpSessionStrategy;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@SpringBootApplication
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = -1)
@Import(SpringConfiguration.class)
public class Run {

    public static void main(String[] args) {
        SpringApplication.run(Run.class, args);
    }


    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurerAdapter() {

            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "OPTIONS", "PATCH", "DELETE");
            }

        };

    }

    @Bean
    public ObjectMapper objectMapper() {
        return JacksonUtils.OBJECT_MAPPER;
    }

    @Bean
    public FilterRegistrationBean loginFilterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new LoginFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("loginFilter");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Bean
    public HttpSessionStrategy httpSessionStrategy() {
        HeaderHttpSessionStrategy sessionStrategy = new HeaderHttpSessionStrategy();
        sessionStrategy.setHeaderName("token");
        return sessionStrategy;
    }

    public class LoginFilter implements Filter {

        private static final String LOGIN = "/api/v1/account";

        //private final Set<String> EXCLUDE_IPS = ImmutableSet.of("0:0:0:0:0:0:0:1", "127.0.0.1");


        @Override
        public void init(FilterConfig filterConfig) throws ServletException {

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;

            //String ip = req.getHeader("WL-Proxy-Client-IP");
            //if (!StringUtils.hasText(ip) || "unknown".equalsIgnoreCase(ip)) {
            //    ip = request.getRemoteAddr();
            //}
            String path = req.getRequestURI();
            if (!"prod".equals(System.getProperty("spring.profiles.active"))) {
                if (path.contains("v2/api-docs")) {
                    chain.doFilter(request, response);
                    return;
                }
            }
            if (req.getMethod().equals("OPTIONS") || path.startsWith(LOGIN) || (SessionConst.session() != null && SessionConst.getCurrentUser() != null)) {
                chain.doFilter(request, response);
                return;
            }
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendError(401, "user not login!");
        }

        @Override
        public void destroy() {

        }
    }

}
